import { containsPoint } from './utils/index.js';
import { EventDispatcher } from './EventDispatcher.js';
import { RectRubber } from './Rubber.Rect.js';


class Rect extends EventDispatcher {
    constructor(x, y, width, height) {
        super();
        this.setup(x, y, width, height);
        /* 状态有 normal focus selected 三种，每种有不同的形态和功能 */
        this.forceState = 'normal';
        this.stroke = '#000000';
        this.fill = '#c4c4c4'; //'rgba(0, 0, 0, 0.0)';
        this.lineWidth = 0;
        this.draggable = true;
        this.rubber = new RectRubber();
    }

    setup(x = 0, y = 0, width = 0, height = 0) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    draw(ctx, ox, oy) {
        ctx.save();
        ctx.beginPath();
        // let stroke = this.getStyleByForceState();
        ctx.fillStyle = this.fill;
        ctx.strokeStyle = this.stroke;
        ctx.lineWidth = this.lineWidth;
        ctx.rect(this.x + ox, this.y + oy, this.width, this.height);
        ctx.fill();
        if (this.lineWidth > 0) {
            ctx.stroke();
        }
        ctx.restore();
        if (this.forceState == 'selected') {
            this.drawHoverBox(ctx, ox, oy);
            this.rubber.draw(ctx, ox, oy);
        }
        if (this.forceState == 'focus') {
            this.drawHoverBox(ctx, ox, oy);
        }
    }

    drawHoverBox(ctx, ox, oy) {
        ctx.save();
        ctx.beginPath();
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#009DFF';
        ctx.rect(this.x + ox, this.y + oy, this.width, this.height);
        ctx.stroke();
        ctx.restore();
    }

    update(ctx, ox, oy) {
        this.rubber.update({
            x: this.x,
            y: this.y,
            w: this.width,
            h: this.height
        });
    }

    containsPoint(ctx, x, y) {
        let rect = this.getBoundingBox(true);
        return containsPoint(rect, x, y);
    }

    getStyleByForceState() {
        let map = {
            /* fill and stroke */
            normal: this.stroke,
            focus: '#00f',
            selected: '#FF00EA',
        }
        return map[this.forceState];
    }

    setForceState(state) {
        if (!['normal', 'focus', 'selected'].includes(state)) {
            throw new TypeError('状态设置错误');
        }
        this.forceState = state;
    }

    getBoundingBox(containsRubber = false) {
        
        let half = this.lineWidth / 2;
        
        // 3和6是控制点的尺寸
        if (containsRubber) {
            return {
                x: this.x - Math.max(half, 3),
                y: this.y - Math.max(half, 3),
                width: this.width + Math.max(this.lineWidth, 6),
                height: this.height + Math.max(this.lineWidth, 6)
            }
        }
        return {
            x: this.x,
            y: this.y,
            width: this.width,
            height: this.height
        }

    }

}

export { Rect };